﻿using OpenAuth.Domain.Interface;
using OpenAuth.Domain.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OpenAuth.Domain.Service
{
    /// <summary>
    /// 领域层定义的领域服务类，实现应用层需要的公共方法
    /// 需要在用户授权领域服务AuthoriseFactory定义【获取用户或者角色可访问的类别明细】
    /// </summary>
    public class SortDetailManagerService
    {
        private ISortDetailRepository _repository;
        private readonly ISortRepository _sortRepository;
        private IRelevanceRepository _relevanceRepository;
        private AuthoriseFactory _factory;

        public SortDetailManagerService(ISortDetailRepository repository,
            ISortRepository sortRepository,
            IRelevanceRepository relevanceRepository,
            AuthoriseFactory authoriseService)
        {
            _repository = repository;
            _sortRepository = sortRepository;
            _relevanceRepository = relevanceRepository;
            _factory = authoriseService;
        }

        public int GetSortDetailCntInOrg(Guid orgId)
        {
            if (orgId == Guid.Empty)
            {
                return _repository.Find(null).Count();
            }
            else
            {
                return _repository.GetSortDetailCntInSorts(_sortRepository.GetSubIds(orgId));
            }
        }

        public List<SortDetail> LoadAll()
        {
            return _repository.Find(null).ToList();
        }

        /// <summary>
        /// 加载用户一个节点下面的一个或全部SortDetails
        /// </summary>
        public dynamic Load(string username, Guid sortId, int page, int rows)
        {
            var service = _factory.Create(username);
            var detailQuery = service.GetSortDetailsQuery();
            //可能报错：
            //System.NotSupportedException
            //Unable to create a constant value of type 'System.Object'.
            //Only primitive types ('such as Int32, String, and Guid') are supported in this context.
            //要在SystemAuthService里override重写GetSortDetailsQuery方法
            int cnt = detailQuery.Count();
            if (!detailQuery.Any()) //用户没有任何资源
            {
                return new
                {
                    total = 0,
                    page = 0,
                    records = 0
                };
            }
            var subIds = _sortRepository.GetSubIds(sortId);


            var query = service.GetSortDetailsQuery().Where(u => sortId == Guid.Empty ||
            (u.SortId != null && subIds.Contains(u.SortId.Value)));
            int total = query.Count();

            if (total <= 0)
                return new
                {
                    total = 0,
                    page = 0,
                    records = 0
                };

            var listVms = new List<dynamic>();
            var sortDetails = query.OrderBy(u => u.SortNo).Skip((page - 1) * rows).Take(rows);
            foreach (var element in sortDetails)
            {
                var accessed = _sortRepository.FindSingle(u => u.Id == element.SortId);
                listVms.Add(new
                {
                    element.Id,
                    element.Name,
                    element.Key,
                    element.SortNo,
                    element.SortId,
                    element.Status,
                    SortName = accessed != null ? accessed.Name : ""
                });
            }

            return new
            {
                records = total,
                total = (int)Math.Ceiling((double)total / rows),
                rows = listVms,
                page = page
            };
        }



        public SortDetail Find(Guid id)
        {
            var SortDetail = _repository.FindSingle(u => u.Id == id);
            if (SortDetail == null) return new SortDetail();

            return SortDetail;
        }

        public void Delete(Guid[] ids)
        {
            _repository.Delete(u => ids.Contains(u.Id));
        }

        public void AddOrUpdate(SortDetail SortDetail)
        {
            if (SortDetail.Id == Guid.Empty)
            {
                _repository.Add(SortDetail);
            }
            else
            {
                _repository.Update(SortDetail);
            }

        }

        /// <summary>
        /// 获取带有授权状态的菜单列表
        /// </summary>
        /// <param name="accessType">授权类型，当前有RoleSortDetail/UserSortDetail</param>
        /// <param name="firstId">
        /// 当为RoleSortDetail时，表示RoleId
        /// 当为UserSortDetail时，表示UserId
        /// </param>
        /// <param name="cId">分类ID</param>
        public List<dynamic> LoadWithAccess(string username, string accessType, Guid firstId, Guid cId)
        {
            var listVms = new List<dynamic>();
            var service = _factory.Create(username);
            if (!service.GetSortDetailsQuery().Any()) //用户没有任何资源
            {
                return listVms;
            }

            var subIds = _sortRepository.GetSubIds(cId);
            var query = service.GetSortDetailsQuery().Where(u => cId == Guid.Empty || (u.SortId != null && subIds.Contains(u.SortId.Value)));

            foreach (var element in query)
            {
                var accessed = _relevanceRepository.FindSingle(u => u.Key == accessType
                    && u.FirstId == firstId && u.SecondId == element.Id);
                listVms.Add(new
                {
                    Id = element.Id,
                    Name = element.Name,
                    Checked = accessed != null,
                    Description = element.Description,
                    Key = element.Key,
                    Status = element.Status
                });
            }
            return listVms;
        }

    }
}
